package com.vehiclemanagement.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vehiclemanagement.entity.AccidentRecord;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 车辆事故记录Mapper接口
 */
@Mapper
public interface AccidentRecordMapper extends BaseMapper<AccidentRecord> {

    /**
     * 自定义分页查询，包含关联的车辆和驾驶员信息
     *
     * @param page     分页参数
     * @param whereSql 自定义WHERE条件
     * @return 包含车辆和驾驶员信息的分页结果
     */
    @Select("SELECT ar.*, v.plate_number, d.name AS driver_name " +
            "FROM accident_record ar " +
            "LEFT JOIN vehicle v ON ar.vehicle_id = v.id " +
            "LEFT JOIN driver d ON ar.driver_id = d.id " +
            "WHERE ${whereSql} " +
            "ORDER BY ar.accident_time DESC")
    IPage<AccidentRecord> selectPageWithInfo(Page<AccidentRecord> page, @Param("whereSql") String whereSql);

    /**
     * 计算指定车辆的累计维修费用
     *
     * @param vehicleId 车辆ID
     * @return 累计维修费用
     */
    @Select("SELECT SUM(repair_cost) FROM accident_record WHERE vehicle_id = #{vehicleId} AND del_flag = 0")
    BigDecimal sumRepairCostByVehicleId(@Param("vehicleId") Long vehicleId);

    /**
     * 计算指定车辆的累计赔偿费用
     *
     * @param vehicleId 车辆ID
     * @return 累计赔偿费用
     */
    @Select("SELECT SUM(compensation_cost) FROM accident_record WHERE vehicle_id = #{vehicleId} AND del_flag = 0")
    BigDecimal sumCompensationCostByVehicleId(@Param("vehicleId") Long vehicleId);

    /**
     * 计算指定车辆的累计保险理赔金额
     *
     * @param vehicleId 车辆ID
     * @return 累计保险理赔金额
     */
    @Select("SELECT SUM(insurance_claim_amount) FROM accident_record WHERE vehicle_id = #{vehicleId} AND del_flag = 0")
    BigDecimal sumInsuranceClaimByVehicleId(@Param("vehicleId") Long vehicleId);

    /**
     * 计算指定车辆的累计实际损失
     *
     * @param vehicleId 车辆ID
     * @return 累计实际损失
     */
    @Select("SELECT SUM(actual_loss) FROM accident_record WHERE vehicle_id = #{vehicleId} AND del_flag = 0")
    BigDecimal sumActualLossByVehicleId(@Param("vehicleId") Long vehicleId);

    /**
     * 计算指定驾驶员的累计事故次数
     *
     * @param driverId 驾驶员ID
     * @return 累计事故次数
     */
    @Select("SELECT COUNT(*) FROM accident_record WHERE driver_id = #{driverId} AND del_flag = 0")
    Integer countAccidentsByDriverId(@Param("driverId") Long driverId);

    /**
     * 按月统计事故数量和损失金额
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 月度统计结果
     */
    @Select("SELECT DATE_FORMAT(accident_time, '%Y-%m') AS month, " +
            "COUNT(*) AS accident_count, " +
            "SUM(repair_cost) AS total_repair_cost, " +
            "SUM(compensation_cost) AS total_compensation_cost, " +
            "SUM(insurance_claim_amount) AS total_insurance_claim, " +
            "SUM(actual_loss) AS total_actual_loss " +
            "FROM accident_record " +
            "WHERE accident_time BETWEEN #{startTime} AND #{endTime} " +
            "AND del_flag = 0 " +
            "GROUP BY DATE_FORMAT(accident_time, '%Y-%m') " +
            "ORDER BY month")
    List<Map<String, Object>> statisticsByMonth(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);

    /**
     * 按事故类型统计事故数量和损失金额
     *
     * @return 事故类型统计结果
     */
    @Select("SELECT accident_type, " +
            "COUNT(*) AS accident_count, " +
            "SUM(repair_cost) AS total_repair_cost, " +
            "SUM(compensation_cost) AS total_compensation_cost, " +
            "SUM(insurance_claim_amount) AS total_insurance_claim, " +
            "SUM(actual_loss) AS total_actual_loss " +
            "FROM accident_record " +
            "WHERE del_flag = 0 " +
            "GROUP BY accident_type " +
            "ORDER BY accident_type")
    List<Map<String, Object>> statisticsByType();

    /**
     * 物理删除记录
     *
     * @param id 记录ID
     * @return 影响的行数
     */
    @Delete("DELETE FROM accident_record WHERE id = #{id}")
    int deletePhysically(@Param("id") Long id);
}